package com.brainardphotography.blog.dao;

import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.brainardphotography.blog.BlogEntry;
import com.brainardphotography.blog.utils.BlogEntryUtil;
import com.brainardphotography.blog.utils.Utils;
import com.googlecode.objectify.NotFoundException;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

public class BlogEntryDAO extends BaseDAO {
	private static final Logger log = Logger.getLogger(BlogEntryDAO.class
			.getName());

	public List<BlogEntry> findAll() {
		Objectify ofy = ObjectifyService.begin();

		List<BlogEntry> entries = ofy.query(BlogEntry.class).order("-created")
				.list();

		return entries;
	}

	public BlogEntry get(String entryID) {
		Objectify ofy = ObjectifyService.begin();

		BlogEntry entry = ofy.get(BlogEntry.class, entryID);
		return entry;
	}

	/**
	 * Returns the most recent blog entry not skipping the home page.
	 * 
	 * @return null if no entries are found.
	 */
	public BlogEntry getHomePageEntry() {
		Objectify ofy = ObjectifyService.begin();

		List<BlogEntry> entries = ofy.query(BlogEntry.class)
				.filter("skipHomePage", false).order("-created").list();

		if (entries.size() > 0) {
			return entries.get(0);
		}

		return null;
	}

	/**
	 * Returns the previous blog entry
	 * 
	 * @param entry
	 */
	public BlogEntry getPreviousEntry(BlogEntry entry) {
		return getPreviousEntry(entry, true);
	}

	public BlogEntry getPreviousEntry(BlogEntry entry, boolean homePageOnly) {
		Objectify ofy = ObjectifyService.begin();

		Query<BlogEntry> query = ofy.query(BlogEntry.class)
				.filter("created <", entry.getCreated()).order("-created");

		if (homePageOnly)
			query.filter("skipHomePage", false);

		return query.limit(1).get();
	}

	/**
	 * Return the most recent entry following the specified entry.
	 * 
	 * @param entry
	 * @return
	 */
	public BlogEntry getNextEntry(BlogEntry entry) {
		return getNextEntry(entry, true);
	}

	public BlogEntry getNextEntry(BlogEntry entry, boolean homePageOnly) {
		Objectify ofy = ObjectifyService.begin();

		Query<BlogEntry> query = ofy.query(BlogEntry.class)
				.filter("created >", entry.getCreated()).order("created");

		if (homePageOnly)
			query.filter("skipHomePage", false);

		return query.limit(1).get();
	}

	/**
	 * Saves a new or existing BlogEntry. If id is not set, a new entry will be created and
	 * the id property will be set from the title.
	 * 
	 * @param entry BlogEntry instance to save.
	 */
	public void save(BlogEntry entry) {
		// TODO Auto-generated method stub
		Objectify ofy = ObjectifyService.begin();

		if (entry.getId() == null || Utils.isStringBlank(entry.getId())) {
			String id = BlogEntryUtil.createEntryIdFromTitle(entry.getTitle());
			entry.setId(id);
			int count = 0;

			while (true) {
				try {
					ofy.get(BlogEntry.class, entry.getId());

					log.info("Found entry with id: " + entry.getId());
					entry.setId(id + "-" + (++count));
				} catch (NotFoundException ex) {
					// We found an ID that works! Excellent.
					break;
				}
			}
		}

		log.info("Saving BlogEntry: " + entry.toString());
		ofy.put(entry);
	}

	public List<BlogEntry> findByDateRange(Date start, Date end) {
		Objectify ofy = ObjectifyService.begin();

		Query<BlogEntry> entries = ofy.query(BlogEntry.class)
				.filter("created >=", start).filter("created <", end);

		System.out.println("Entries Query: " + entries.toString());

		return entries.list();
	}

	public List<BlogEntry> findByDate(Date date) {
		return findByDateRange(date, Utils.getTomorrow(date));
	}
	
	public List<BlogEntry> findByTag(String tag) {
		Objectify ofy = ObjectifyService.begin();
		
		Query<BlogEntry> entries = ofy.query(BlogEntry.class)
				.filter("tags =", tag)
				.order("created");
		
		return entries.list();
	}
}
